
local ElementUI = _ENV.import("./ElementUI.lua");
-- local Style = _ENV.import("../Style/Style.lua");
-- local Layout = _ENV.import("../Style/Layout.lua");

local Element = commonlib.inherit(ElementUI);

Element:Property("Name");
-- Element:Property("DefaultStyle");
-- Element:Property("DefaultHoverStyle");
-- Element:Property("DefaultFocusStyle");
-- Element:Property("Attr");
-- Element:Property("Directive");
-- Element:Property("Layout");
-- Element:Property("Hover", false, "IsHover");
-- Element:Property("Focus", false, "IsFocus");
-- Element:Property("ZIndex", 0);
-- Element:Property("FinishLayout", true, "IsFinishLayout");          -- 是否布局结束
-- Element:Property("Exist", true, "IsExist");                        -- 默认存在
-- Element:Property("ExistScrollBar", false, "IsExistScrollBar");     -- 存在滚动条

-- function Element:ctor()
--     self:SetName("Element");
--     -- self.childrens, self.zindex_childrens = {}, {};  -- 子元素
-- end

-- function Element:Init(xmlnode, parent)
--     Element._super.Init(self, xmlnode, parent);
--     return self;
-- end



-- function Element:CompileDirective()
--     local xmlnode = self:GetXmlNode();
--     local attr = self:GetAttr();
--     local scope = self:GetScope();
--     local indexInParent = self:GetIndexInParent();
--     local directive = {["v-attr"] = {}, ["v-on"] = {}};
--     local G = self:GetWindow():GetG();
--     local isCompileFinish = false;
--     for _, key in ipairs(commonlib.keys(attr)) do
--         local value = attr[key];
--         if (key == "v-if") then
--             local expr = "return " .. value;
--             directive["v-if"] = G.__new_scope_expr__(expr, nil, scope, function(expr_value)
--                 self:SetExist(expr_value);
--             end);
--         elseif (key == "v-model") then
--             local attrName = string.sub(key, 8);
--             local attrExpr = "return " .. value;
--             local keys = commonlib.split(value, ".");
--             directive["v-model"] = G.__new_scope_expr__(attrExpr, nil, scope, function(expr_value)
--                 self:SetAttrValue("value", expr_value);
--             end);
--             self:SetAttrValue("onchange", function(el, val)
--                 local subscope, size = scope, #keys;
--                 for i = 1, size - 1 do subscope = subscope[keys[i]] end
--                 subscope[keys[size]] = val;
--             end);
--         elseif (key == "v-for") then
--             -- 解析 v-for 表达式
--             local vfor = value;
--             local inIndex = string.find(vfor, " in ", 1, true);
--             if (not inIndex) then 
--                 local kvexp = string.sub(vfor, 1, inIndex -1);
--                 local listexp = string.sub(vfor, inIndex + 4);
--                 local v, k = string.match(kvexp, "(%a%w-)%s*,%s*(%a%w+)");
--                 if (not v) then v = string.match(kvexp, "(%a%w-)") end
--                 v = v or "value"
--                 k = k or "index";
--                 local expr = "return " .. listexp;
--                 local clones = {};
--                 local last_size = 0;
--                 directive["v-for"] = G.__new_scope_expr__(expr, nil, scope, function(expr_value)
--                     local size = 0;
--                     if (type(expr_value) == "table") then 
--                         size = #expr_value;
--                     elseif (type(expr_value) == "number") then
--                         size = math.max(0, math.floor(expr_value));
--                     else 
--                         size = 0;
--                     end
--                 end);
--             end 
--         elseif (string.sub(key, 1, 7) == "v-bind:") then
--             local attrName = string.sub(key, 8);
--             local attrExpr = "return " .. value;
--             local attrDefaultValue = attr[attrName];
--             directive["v-attr"][attrName] = G.__new_scope_expr__(attrExpr, attrDefaultValue, scope, function(expr_value)
--                 self:SetAttrValue(attrName, expr_value);
--             end);
--         elseif (string.sub(key, 1, 5) == "v-on:") then
--             local attrName = string.sub(key, 6);
--             local attrValue = commonlib.loadstring(value, scope);
--             self:SetAttrValue(attrName, attrValue);
--         end
--     end
--     -- 文本节点
--     if (not xmlnode.name and xmlnode.text) then
--         local args = ""
--         local text = string.gsub(commonlib.trim(xmlnode.text), "{{(.-)}}", function(code)
--             args = args .. ", " .. code;
--             return "%s";
--         end);
--         local expr = string.format([==[return string.format([[%s]]%s)]==], text, args);
--         directive["v-text"] = G.__new_scope_expr__(expr, nil, scope, function(expr_value)
--             self:SetText(expr_value);
--         end);
--     end

--     for child in self:ChildrenIterator() do
--         child:CompileDirective();
--     end

--     isCompileFinish = true;
--     self:SetDirective(directive);
-- end


-- function Element:GetStyleValue(style_name, default_value)
--     return self:GetStyle():GetValue(style_name, default_value);
-- end

-- --  layout
-- function Element:OnBeforeUpdateLayout()
--     -- 提取生效样式后即可确定的样式值, 外观相关
--     self.__style_font_weight__ = self:GetStyleValue("font-weight");
--     self.__style_font_slant__ = self:GetStyleValue("font-style");
--     self.__style_font_family__ = self:GetStyleValue("font-family");
--     self.__style_font_size__ = self:GetStyle():GetFontSize();
--     self.__style_line_height__ = self:GetStyle():GetLineHeight();
--     self.__style_color__ = self:GetStyleValue("color", 0xff);
--     self.__style_background_color__ = self:GetStyleValue("background-color");
--     self.__style_outline_width__ = self:GetStyleValue("outline-width", 0);
--     self.__style_outline_color__ = self:GetStyleValue("outline-color");
--     self.__style_border_radius__ = self:GetStyleValue("border-radius", 0);
--     self.__style_border_color__ = self:GetStyleValue("border-color");
--     self.__style_border_width__ = self:GetStyleValue("border-width");
--     self.__style_border_top_color__ = self:GetStyleValue("border-top-color");
--     self.__style_border_right_color__ = self:GetStyleValue("border-right-color");
--     self.__style_border_bottom_color__ = self:GetStyleValue("border-bottom-color");
--     self.__style_border_left_color__ = self:GetStyleValue("border-left-color");
-- end

-- function Element:OnBeginLayout()
--     -- 标记开始
--     self:SetFinishLayout(false);
--     -- 开始布局
--     self:GetLayout():OnBegin();
-- end

-- function Element:OnBeforeUpdateChildrenLayout()
--     -- 提取布局开始后可以确定的样式, 元素自身尺寸相关
--     self:GetLayout():OnBeforeUpdateChildrenLayout();
-- end

-- function Element:OnUpdateChildrenLayout()
--     for el in self:ChildrenIterator() do el:UpdateLayout() end
-- end

-- function Element:OnAfterUpdateChildrenLayout()
--     self:GetLayout():OnAfterUpdateChildrenLayout();
-- end

-- function Element:OnUpdateLayout()
--     self:GetLayout():OnUpdateLayout();
-- end

-- function Element:OnEndLayout()
--     -- 布局结束
--     self:GetLayout():OnEnd();
--     -- 标记结束
--     self:SetFinishLayout(true);
--     -- 布局完成排序元素
--     self:SortChildrens();
-- end

-- -- -- 布局更新完成, 递归通知子元素更新自己真实位置
-- -- function Element:OnAfterUpdateLayout()
-- --     -- 布局完成回调
-- --     self:GetLayout():OnAfterUpdateLayout();
    
-- --     -- 提取父元素布局完成才能确定的样式值, 主要为位置与尺寸
-- --     local layout = self:GetLayout();
-- --     self.__is_fixed_position__ = layout:IsFixedElement();  -- 是否固定定位
-- --     self.__is_absolute_position = layout:IsAbsoluteElement();
-- --     self.__rel_x__, self.__rel_y__ = layout:GetPos();
-- --     self.__width__, self.__height__ = layout:GetWidthHeight();
-- --     self.__padding_top__, self.__padding_right__, self.__padding_bottom__, self.__padding_left__ = layout:GetPadding();
-- --     self.__border_top_width__, self.__border_right_width__, self.__border_bottom_width__, self.__border_left_width__ = layout:GetBorder();
-- --     self.__content_width__, self.__content_height__ = layout:GetContentWidthHeight();
-- --     self.__real_content_width__, self.__real_content_height__ = layout:GetRealContentWidthHeight();
-- --     self.__is_exist_x_scroll_bar__ = layout:IsCanScrollX();
-- --     self.__is_exist_y_scroll_bar__ = layout:IsCanScrollY();
-- --     self.__is_clip_overflow__ = layout:IsClipOverflow();
-- --     self.__is_exist_scroll_bar__ = self.__is_exist_x_scroll_bar__ or self.__is_exist_y_scroll_bar__;
-- --     self.__scroll_x__ = self.__scroll_x__ or 0;
-- --     self.__scroll_y__= self.__scroll_y__ or 0;

-- --     local scrollbar_thumb_offset = 1;
-- --     local scrollbar_thumb_color = 0xa8a8a8ff;
-- --     local scrollbar_track_size = 10;
-- --     local scrollbar_track_color = 0xf1f1f1ff;
-- --     if (self.__is_exist_y_scroll_bar__) then
-- --         -- scrollbar track
-- --         self.__scrollbar_y_track_color__ = self.__scrollbar_y_track_color__ or scrollbar_track_color;
-- --         self.__scrollbar_y_track_width__ = self.__scrollbar_y_track_width__ or scrollbar_track_size;
-- --         -- scrollbar thumb
-- --         self.__scrollbar_y_thumb_offset__ = self.__scrollbar_y_thumb_offset__ or scrollbar_thumb_offset;
-- --         self.__scrollbar_y_thumb_color__ = self.__scrollbar_y_thumb_color__ or scrollbar_thumb_color;
-- --         self.__scrollbar_y_thumb_width__ = self.__scrollbar_y_track_width__ - 2 * self.__scrollbar_y_thumb_offset__;
-- --         self.__scrollbar_y_thumb_height__ = self.__height__ * self.__content_height__ / self.__real_content_height__;
-- --         self.__scrollbar_y_thumb_x__ = self.__width__ - self.__scrollbar_y_track_width__ + self.__scrollbar_y_thumb_offset__;
-- --         self.__scrollbar_y_thumb_y__ = 0;
-- --         self.__max_scroll_y__ = self.__real_content_height__ - self.__content_height__;
    
-- --     end

-- --     if (self.__is_exist_x_scroll_bar__) then
-- --         -- scrollbar track
-- --         self.__scrollbar_x_track_color__ = self.__scrollbar_x_track_color__ or scrollbar_track_color;
-- --         self.__scrollbar_x_track_height__ = self.__scrollbar_x_track_height__ or scrollbar_track_size;
-- --         -- scrollbar thumb
-- --         self.__scrollbar_x_thumb_offset__ = self.__scrollbar_x_thumb_offset__ or scrollbar_thumb_offset;
-- --         self.__scrollbar_x_thumb_color__ = self.__scrollbar_x_thumb_color__ or scrollbar_thumb_color;
-- --         self.__scrollbar_x_thumb_width__ = self.__width__ * self.__content_width__ / self.__real_content_width__;
-- --         self.__scrollbar_y_thumb_height__ = self.__scrollbar_x_track_height__ - 2 * self.__scrollbar_y_thumb_offset__;
-- --         self.__scrollbar_x_thumb_x__ = 0;
-- --         self.__scrollbar_y_thumb_y__ = self.__height__ - self.__scrollbar_x_track_height__ + self.__scrollbar_y_thumb_offset__;
-- --         self.__max_scroll_x__ = self.__real_content_width__ - self.__content_width__;
-- --     end

-- --     -- 滚动到指定位置
-- --     self:ScrollTo(self.__scroll_x__, self.__scroll_y__);
-- -- end



-- -- position
-- function Element:UpdatePosition()
--     local layout = self:GetLayout();
--     local __x__, __y__ = 0, 0;                          -- 绝对坐标
--     local __view_x__, __view_y__ = 0, 0;                -- 视图坐标
--     local __scroll_x__, __scroll_y__ = 0, 0;            -- 滚动坐标
--     self.__rel_x__, self.__rel_y__ = layout:GetPos();   -- 相对父元素偏移量
--     if (layout:IsFixedElement() or not self:GetParent()) then
--         __x__, __y__ = self:GetWindow():GetWindowPosition();
--         __view_x__, __view_y__ = __x__, __y__;
--     else
--         __x__, __y__ = self:GetParent():GetPosition();
--         __view_x__, __view_y__ = self:GetParent():GetViewPosition();
--         __scroll_x__, __scroll_y__ = self:GetParent():GetScrollXY();
--     end
--     self.__x__, self.__y__ = __x__ + self.__rel_x__, __y__ + self.__rel_y__;
--     self.__view_x__, self.__view_y__ = __view_x__ + self.__rel_x__ - __scroll_x__, __view_y__ + self.__rel_y__ - __scroll_y__; 
--     self.__content_x__ = self.__x__ + self.__padding_left__ + self.__border_left_width__;
--     self.__content_y__ = self.__y__ + self.__padding_top__ + self.__border_top_width__;

--     -- 递归更新子元素位置
--     for child in self:ChildrenIterator() do child:UpdatePosition() end 
-- end

-- -- 获取内容位置
-- function Element:GetContentPosition()
--     return self.__content_x__ or self.x, self.__content_y__ or self.y, self.__content_width__ or 0, self.__content_height__ or 0;
-- end

-- -- 获取真实内容宽高
-- function Element:GetRealContentWidthHeight()
--     return self.__real_content_width__ or 0, self.__real_content_height__ or 0;
-- end

-- -- 获取位置
-- function Element:GetPosition()
--     return self.__x__ or 0, self.__y__ or 0, self.__width__ or 0, self.__height__ or 0;
-- end

-- -- 获取视图位置 含滚动偏移
-- function Element:GetViewPosition()
--     return self.__view_x__ or 0, self.__view_y__ or 0, self.__width__, self.__height__ or 0;
-- end

-- -- 是否包含点 窗口坐标
-- function Element:Contain(sx, sy)
--     local x, y, w, h = self:GetViewPosition();
--     return x <= sx and sx <= (x + w) and y <= sy and sy <= (y + h);
-- end

-- -- 获取滚动值
-- function Element:GetScrollXY()
--     return self.__scroll_x__ or 0, self.__scroll_y__ or 0;
-- end

-- -- 获取鼠标XY
-- function Element:GetMouseXY()
--     return commonlib.__mouse_x__ or 0, commonlib.__mouse_y__ or 0;
-- end

-- -- 滚动
-- function Element:ScrollTo(scrollX, scrollY)
--     if (self.__is_exist_y_scroll_bar__) then
--         self.__scroll_y__ = math.max(0, math.min(scrollY or 0, self.__max_scroll_y__));
--         self.__scrollbar_y_thumb_y__ = self.__scroll_y__ * self.__height__ / self.__real_content_height__; 
--     end

--     if (self.__is_exist_x_scroll_bar__) then
--         self.__scroll_x__ = math.max(0, math.min(scrollX or 0, self.__max_scroll_x__));
--         self.__scrollbar_x_thumb_x__ = self.__scroll_x__ * self.__width__ / self.__real_content_width__;
--     end
--     -- 更新子元素渲染列表
--     self:SortChildrens();
--     self:UpdatePosition();
-- end

-- -- 获取鼠标元素
-- function Element:GetMouseElement(x, y)
--     -- 优先取子元素
--     for el in self:EventChildrenIterator() do
--         local target_el = el:GetMouseElement(x, y);
--         if (target_el) then return target_el end 
--     end
--     -- 再检测自己
--     return self:Contain(x, y) and self or nil;
-- end

-- -- 坐标转换
-- function Element:ScreenXYToWindowXY(sx, sy)
--     local windowX, windowY = self:GetWindow():GetWindowPosition();
--     return sx - windowX, sy - windowY;
-- end

-- function Element:WindowXYToScreenXY(wx, wy)
--     local windowX, windowY = self:GetWindow():GetWindowPosition();
--     return wx + windowX, wy + windowY;
-- end

-- function Element:ScreenXYToElementXY(sx, sy)
--     return sx - (self.__view_x__ or 0), sy - (self.__view_y__ or 0);
-- end

-- function Element:ElementXYToScreenXY(x, y)
--     return x + (self.__view_x__ or 0), y + (self.__view_y__ or 0);
-- end

-- -- 是否可见
-- function Element:IsVisible()
--     if (not self:IsExist() or not self:GetLayout():IsVisible()) then return false end 
--     local parent = self:GetParent();
--     if (parent and parent.__is_clip_overflow__) then
--         local x, y, w, h = self.__rel_x__, self.__rel_y__, self.__width__, self.__height__;
--         local __scroll_x__, __scroll_y__ = parent.__scroll_x__, parent.__scroll_y__;
--         local width, height = parent.__width__, parent.__height__;
--         x, y = x - __scroll_x__, y - __scroll_y__;
--         return not ((x + w) <= 0 or width <= x or (y + h) <= 0 or height <= y); 
--     end

--     return true;
-- end

-- function Element:Hide()
--     self:SetExist(false);
--     local parent = self:GetParent();
--     if (parent) then parent:SortChildrens() end
-- end

-- function Element:Show()
--     self:SetExist(true);
--     self:ApplyStyle();
--     -- (self:GetParent() or self):UpdateLayout();
--     self:UpdateLayout();
--     self:UpdatePosition();
--     local parent = self:GetParent();
--     if (parent) then parent:SortChildrens() end
-- end

-- function Element:OnRender()
--     self:OnBeforeRender();
--     self:Render();
--     self:OnBeforeRenderChildren();
--     self:OnRenderChildren();
--     self:OnAfterRenderChildren();
--     self:RenderScrollBar();
--     self:OnAfterRender();
-- end

-- function Element:OnBeforeRender()
-- end

-- function Element:OnBeforeRenderChildren()
-- end

-- -- 绘制子元素
-- function Element:OnRenderChildren()
--     if (self.__is_clip_overflow__) then
--         local x, y, w, h = self:GetPosition();
--         self:Save();
--         self:DrawRectangle(x, y, w, h, false);
--         self:Clip();
--         self:Translate(-self.__scroll_x__, -self.__scroll_y__);
--     end
--     for el in self:RenderChildrenIterator() do
--         el:OnRender();
--     end
--     if (self.__is_clip_overflow__) then
--         self:Translate(self.__scroll_x__, self.__scroll_y__);
--         self:Restore();
--     end
-- end

-- function Element:OnAfterRenderChildren()
-- end

-- function Element:OnAfterRender()
-- end

-- -- render
-- function Element:Render()
--     local x, y, w, h = self:GetPosition();
--     local outlineWidth = self.__style_outline_width__;
--     local borderRadius = self.__style_border_radius__;
--     if (outlineWidth > 0) then x, y, w, h = x - outlineWidth, y - outlineWidth, w + outlineWidth, h + outlineWidth end 
--     self:Save();
--     if (borderRadius > 0) then
--         self:DrawArc(x + borderRadius, y + borderRadius, borderRadius, 0, 360, false);
--         self:DrawArc(x + w - borderRadius, y + borderRadius, borderRadius, 0, 360, false);
--         self:DrawArc(x + borderRadius, y + h - borderRadius, borderRadius, 0, 360, false);
--         self:DrawArc(x + w - borderRadius, y + h - borderRadius, borderRadius, 0, 360, false);
--         self:DrawRectangle(x, y + borderRadius, w, h - 2 * borderRadius, false);
--         self:DrawRectangle(x + borderRadius, y, w - 2 * borderRadius, h, false);
--     else 
--         self:DrawRectangle(x, y, w, h, false);
--     end
--     self:Clip();
--     self:RenderOutline();
--     self:RenderBackground();
--     self:RenderBorder();
--     self:RenderContent();
--     self:Restore();
-- end

-- -- 绘制外框线
-- function Element:RenderOutline()
--     local x, y, w, h = self:GetPosition();
--     local outlineWidth, outlineColor = self.__style_outline_width__, self.__style_outline_color__;
--     if (not outlineWidth or not outlineColor) then return end
--     self:SetBrushColor(outlineColor);
--     self:DrawRectangle(x - outlineWidth, y - outlineWidth , w + 2 * outlineWidth, outlineWidth);      -- 上
--     self:DrawRectangle(x + w, y - outlineWidth, outlineWidth, h + 2 * outlineWidth);                  -- 右
--     self:DrawRectangle(x - outlineWidth, y + h , w + 2 * outlineWidth, outlineWidth);                 -- 下
--     self:DrawRectangle(x - outlineWidth, y - outlineWidth, outlineWidth, h + 2 * outlineWidth);       -- 左
-- end

-- function Element:RenderBackground()
--     local x, y, w, h = self:GetPosition();
--     local backgroundColor = self.__style_background_color__;
--     local backgroundImage = self.__style_background_image__;
--     if (backgroundImage) then
--         self:DrawImage(x, y, w, h, backgroundImage.filepath, backgroundColor);
--     else
--         if (backgroundColor) then 
--             self:SetBrushColor(backgroundColor);
--         else 
--             self:SetBrushColor(0x0);
--         end 
--         self:DrawRectangle(x, y, w, h);
--     end
-- end

-- function Element:RenderBorder()
--     local x, y, w, h = self:GetPosition();
--     local borderWidth, borderColor = self.__style_border_width__, self.__style_border_color__;
--     if (borderWidth and borderWidth > 0 and borderColor) then 
--         self:SetBrushColor(borderColor);
--         self:DrawRectangle(x, y, w, borderWidth);                          -- 上
--         self:DrawRectangle(x + w - borderWidth, y , borderWidth, h);       -- 右
--         self:DrawRectangle(x, y + h - borderWidth, w, borderWidth);        -- 下
--         self:DrawRectangle(x, y , borderWidth, h);                         -- 左
--     else 
--         borderWidth, borderColor = self.__style_border_top_width__, self.__style_border_top_color__;
--         if (borderWidth and borderWidth > 0 and borderColor) then 
--             self:SetBrushColor(borderColor);
--             self:DrawRectangle(x, y, w, borderWidth); 
--         end
--         borderWidth, borderColor = self.__style_border_right_width__, self.__style_border_right_color__;
--         if (borderWidth and borderWidth > 0 and borderColor) then 
--             self:SetBrushColor(borderColor);
--             self:DrawRectangle(x + w - borderWidth, y , borderWidth, h); 
--         end
--         borderWidth, borderColor = self.__style_border_bottom_width__, self.__style_border_bottom_color__;
--         if (borderWidth and borderWidth > 0 and borderColor) then 
--             self:SetBrushColor(borderColor);
--             self:DrawRectangle(x, y + h - borderWidth, w, borderWidth);
--         end
--         borderWidth, borderColor = self.__style_border_left_width__, self.__style_border_left_color__;
--         if (borderWidth and borderWidth > 0 and borderColor) then 
--             self:SetBrushColor(borderColor);
--             self:DrawRectangle(x, y , borderWidth, h);
--         end
--     end
-- end

-- function Element:RenderScrollBar()
--     local x, y, w, h = self:GetPosition();
--     if (self.__is_exist_y_scroll_bar__) then
--         -- scrollbar track
--         self:SetBrushColor(self.__scrollbar_y_track_color__);
--         self:DrawRectangle(x + w - self.__scrollbar_y_track_width__, y, self.__scrollbar_y_track_width__, h);
--         -- scrollbar thumb
--         self:SetBrushColor(self.__scrollbar_y_thumb_color__);
--         self:DrawRectangle(x + self.__scrollbar_y_thumb_x__, y + self.__scrollbar_y_thumb_y__, self.__scrollbar_y_thumb_width__, self.__scrollbar_y_thumb_height__);
--     end

--     if (self.__is_exist_x_scroll_bar__) then
--         -- scrollbar track
--         self:SetBrushColor(self.__scrollbar_x_track_color__);
--         self:DrawRectangle(x, y + h - self.__scrollbar_x_track_height__, w, self.__scrollbar_x_track_height__);
--         -- scrollbar thumb
--         self:SetBrushColor(self.__scrollbar_x_thumb_color__);
--         self:DrawRectangle(x + self.__scrollbar_x_thumb_x__, y + self.__scrollbar_x_thumb_y__, self.__scrollbar_x_thumb_width__, self.__scrollbar_x_thumb_height__);
--     end
-- end

-- function Element:RenderContent()
-- end

-- function Element:ApplyStyleFontToPaint()
--     self:SetFontSize(self.__style_font_size__);
--     if (self.__style_color__) then self:SetFontColor(self.__style_color__) end 
--     self:SetFont(self.__style_font_weight__, self.__style_font_slant__, self.__style_font_family__);
-- end

-- function Element:GetLineHeight()
--     return self.__style_line_height__ or 0;
-- end



-- -- 调用事件函数
-- function Element:CallAttrFunction(attrName, defaultValue, ...)
--     local func = self:GetAttrFunctionValue(attrName, defaultValue);
--     if (not func) then return nil end
--     return func(self, ...);
-- end

-- -- 常用属性
-- -- 属性ID
-- function Element:GetAttrId()
--     return self:GetAttrStringValue("id");
-- end

-- -- 是否禁用
-- function Element:IsDisabled()
--     return self:GetAttrBoolValue("disabled") == true and true or false;
-- end

-- -- 元素属性值更新
-- function Element:OnAttrValueChange(attrName, attrValue, oldAttrValue)
--     if (attrName == "class") then 
--         self:UpdateLayout();
--     end
--     if (attrName == "style") then 
--         self:GetStyle():SetInlineStyle(attrValue); 
--         self:UpdateLayout();
--     end
-- end

-- -- 设置属性值
-- function Element:SetAttrValue(attrName, attrValue)
--     local attr = self:GetAttr();
--     local oldAttrValue = attr[attrName];
--     attr[attrName] = attrValue;
--     if (oldAttrValue == attrValue) then return end
--     self:OnAttrValueChange(attrName, attrValue, oldAttrValue);
-- end

-- -- 设置样式值
-- function Element:SetInlineStyleValue(styleKey, styleValue)
--     self:GetStyle():GetInlineStyle()[styleKey] = styleValue;
-- end



-- -- 排序子元素 z-index 由小到大排列
-- function Element:SortChildrens()
--     commonlib.cleartable(self.zindex_childrens);
    
--     for _, el in ipairs(self.childrens) do
--         if (el:IsVisible()) then
--             local zindex = el:GetZIndex();
--             local size = #(self.zindex_childrens);
--             local index = 1;
--             while (index <= size) do
--                 local _el = self.zindex_childrens[index];
--                 if (zindex < _el:GetZIndex()) then break end
--                 index = index + 1;
--             end 
--             table.insert(self.zindex_childrens, index, el);
--         end
--     end
-- end

-- -- 渲染序子元素迭代器  z-index 由小到大迭代
-- function Element:RenderChildrenIterator()
--     local index = 0;
--     return function()
--         index = index + 1;
--         return self.zindex_childrens[index];
--     end
-- end

-- -- 事件序 z-index 由大到小迭代
-- function Element:EventChildrenIterator()
--     local size = #(self.zindex_childrens);
--     local index = size + 1;
--     return function()
--         index = index - 1;
--         return self.zindex_childrens[index];
--     end
-- end

-- -- 是否捕获鼠标
-- function Element:IsMouseCaptured()
--     return self:GetMouseCapture() ~= nil;
-- end

-- -- 获取鼠标捕获
-- function Element:GetMouseCapture()
--     return self:GetWindow():GetMouseCaptureElement();
-- end

-- -- 捕获鼠标
-- function Element:CaptureMouse()
--     if (self:IsMouseCaptured()) then return end 

--     local win = self:GetWindow();
--     win:SetMouseCaptureElement(self);
--     win.SetMouseCaptureWindow(win);
-- end

-- -- 释放鼠标捕获
-- function Element:ReleaseMouse()
-- 	if (self:GetMouseCapture() ~= self) then return end

--     local win = self:GetWindow();
--     win:SetMouseCaptureElement(nil);
--     win.SetMouseCaptureWindow(nil);
-- end

-- -- Event
-- function Element:OnMouseDownCapture()
-- end
-- function Element:OnMouseUpCapture()
-- end
-- function Element:OnMouseMoveCapture()
-- end
-- function Element:OnMouseWheelCapture()
-- end
-- function Element:OnMouseCapture()
-- end
-- function Element:OnMouse(event)
-- end
-- function Element:OnMouseDown(event)
--     self:CallAttrFunction("onmousedown", nil, event);
-- end
-- function Element:OnMouseUp(event)
--     self:CallAttrFunction("onmouseup", nil, event);
-- end
-- function Element:OnMouseMove(event)
--     self:CallAttrFunction("onmousemove", nil, event);
-- end
-- function Element:OnMouseWheel(event)
--     self:ScrollTo(self.__scroll_x__, (self.__scroll_y__ or 0) + event:GetMouseWheelDelta());
--     self:CallAttrFunction("onmousewheel", nil, event);
-- end
-- function Element:OnKeyDown(event)
--     self:CallAttrFunction("onkeydown", nil, event);
-- end
-- function Element:OnKeyUp(event)
--     self:CallAttrFunction("onkeyup", nil, event);
-- end
-- function Element:OnChar(event)
--     self:CallAttrFunction("onchar", nil, event);
-- end
-- function Element:OnClick(event)
--     self:CallAttrFunction("onclick", nil, event);
-- end

-- -- 失去焦点事件
-- function Element:OnFocusOut()
--     self:CallAttrFunction("onblur", nil);
-- end

-- -- 获取焦点事件
-- function Element:OnFocusIn()
--     self:CallAttrFunction("onfocus", nil);
-- end

-- -- 获取聚焦元素
-- function Element:GetFocus()
--     return self:GetWindow():GetFocusElement();
-- end

-- -- 是否是聚焦元素
-- function Element:IsFocus()
--     return self:GetFocus() == self;
-- end

-- -- 元素主动聚焦
-- function Element:FocusIn()
--     self:SetFocus(self);
-- end

-- -- 元素主动失去焦点
-- function Element:FocusOut()
--     self:SetFocus(nil);
-- end

-- -- 设置聚焦元素
-- function Element:SetFocus(element)
--     local window = self:GetWindow();
--     if (not window) then return end
--     -- 获取旧焦点
--     local focusElement = window:GetFocusElement();
--     if (focusElement == element) then return end

--     -- 失焦, 设置聚焦元素为空
--     window:SetFocusElement(nil);
--     if (focusElement) then focusElement:OnFocusOut() end

--     -- 聚焦, 再次设置聚焦元素, OnFocusOut 很有可能破坏聚焦元素
--     window:SetFocusElement(element);
--     if (element) then element:OnFocusIn() end
-- end

return Element;




-- -- 元素类
-- function Element:CreateElementClassMap() 
--     if (self.__element_class_map__) then return self.__element_class_map__ end
--     local parent_element_class_map = self:GetParentElementClassMap();
--     self.__element_class_map__ = {};
--     if (parent_element_class_map) then setmetatable(self.__element_class_map__, {__index = parent_element_class_map}) end 
--     return self.__element_class_map__;    
-- end

-- function Element:GetParentElementClassMap()
--     local parent = self:GetParent();
--     return parent and parent:GetElementClassMap() or commonlib.GetElementClassMap();
-- end

-- function Element:GetElementClassMap()
--    return self.__element_class_map__ or self:GetParentElementClassMap() or self:CreateElementClassMap();
-- end

-- function Element:RegisterElementClass(tagname, class)
--     local element_class_map = self:CreateElementClassMap();
--     element_class_map[string.lower(tagname)] = class;
-- end

-- function Element:RemoveElementClass(tagname)
--     local element_class_map = self:CreateElementClassMap();
--     element_class_map[string.lower(tagname)] = nil;
-- end

-- function Element:GetElementDefaultClass()
--     return Element;
-- end

-- function Element:GetElementClass(tagname, defaultElementClass)
--     local element_class_map = self:GetElementClassMap();
--     return element_class_map[string.lower(tagname)] or defaultElementClass or self:GetElementDefaultClass();
-- end